﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using HalconDotNet;
namespace halconMa
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            
            Application.Run(new Form1());
        }
    }
    public partial class HDevelopExport
    {
        public HTuple hv_ExpDefaultWinHandle;
        // Local iconic variables 

        HObject ho_Mark;


        // Local control variables 

        HTuple hv_AcqHandle;

        public void HDevelopStop()
        {
            MessageBox.Show("Press button to continue", "Program stop");
        }
        // Procedures 
        // External procedures 
        // Chapter: Graphics / Text
        // Short Description: This procedure writes a text message.
        public void disp_message(HTuple hv_WindowHandle, HTuple hv_String, HTuple hv_CoordSystem,
            HTuple hv_Row, HTuple hv_Column, HTuple hv_Color, HTuple hv_Box)
        {


            // Local control variables 

            HTuple hv_Red, hv_Green, hv_Blue, hv_Row1Part;
            HTuple hv_Column1Part, hv_Row2Part, hv_Column2Part, hv_RowWin;
            HTuple hv_ColumnWin, hv_WidthWin = new HTuple(), hv_HeightWin;
            HTuple hv_MaxAscent, hv_MaxDescent, hv_MaxWidth, hv_MaxHeight;
            HTuple hv_R1 = new HTuple(), hv_C1 = new HTuple(), hv_FactorRow = new HTuple();
            HTuple hv_FactorColumn = new HTuple(), hv_Width = new HTuple();
            HTuple hv_Index = new HTuple(), hv_Ascent = new HTuple(), hv_Descent = new HTuple();
            HTuple hv_W = new HTuple(), hv_H = new HTuple(), hv_FrameHeight = new HTuple();
            HTuple hv_FrameWidth = new HTuple(), hv_R2 = new HTuple();
            HTuple hv_C2 = new HTuple(), hv_DrawMode = new HTuple(), hv_Exception = new HTuple();
            HTuple hv_CurrentColor = new HTuple();

            HTuple hv_Color_COPY_INP_TMP = hv_Color.Clone();
            HTuple hv_Column_COPY_INP_TMP = hv_Column.Clone();
            HTuple hv_Row_COPY_INP_TMP = hv_Row.Clone();
            HTuple hv_String_COPY_INP_TMP = hv_String.Clone();

            // Initialize local and output iconic variables 

            //This procedure displays text in a graphics window.
            //
            //Input parameters:
            //WindowHandle: The WindowHandle of the graphics window, where
            //   the message should be displayed
            //String: A tuple of strings containing the text message to be displayed
            //CoordSystem: If set to 'window', the text position is given
            //   with respect to the window coordinate system.
            //   If set to 'image', image coordinates are used.
            //   (This may be useful in zoomed images.)
            //Row: The row coordinate of the desired text position
            //   If set to -1, a default value of 12 is used.
            //Column: The column coordinate of the desired text position
            //   If set to -1, a default value of 12 is used.
            //Color: defines the color of the text as string.
            //   If set to [], '' or 'auto' the currently set color is used.
            //   If a tuple of strings is passed, the colors are used cyclically
            //   for each new textline.
            //Box: If set to 'true', the text is written within a white box.
            //
            //prepare window
            HOperatorSet.GetRgb(hv_ExpDefaultWinHandle, out hv_Red, out hv_Green, out hv_Blue);
            HOperatorSet.GetPart(hv_ExpDefaultWinHandle, out hv_Row1Part, out hv_Column1Part,
                out hv_Row2Part, out hv_Column2Part);
            HOperatorSet.GetWindowExtents(hv_ExpDefaultWinHandle, out hv_RowWin, out hv_ColumnWin,
                out hv_WidthWin, out hv_HeightWin);
            HOperatorSet.SetPart(hv_ExpDefaultWinHandle, 0, 0, hv_HeightWin - 1, hv_WidthWin - 1);
            //
            //default settings
            if ((int)(new HTuple(hv_Row_COPY_INP_TMP.TupleEqual(-1))) != 0)
            {
                hv_Row_COPY_INP_TMP = 12;
            }
            if ((int)(new HTuple(hv_Column_COPY_INP_TMP.TupleEqual(-1))) != 0)
            {
                hv_Column_COPY_INP_TMP = 12;
            }
            if ((int)(new HTuple(hv_Color_COPY_INP_TMP.TupleEqual(new HTuple()))) != 0)
            {
                hv_Color_COPY_INP_TMP = "";
            }
            //
            hv_String_COPY_INP_TMP = ((("" + hv_String_COPY_INP_TMP) + "")).TupleSplit("\n");
            //
            //Estimate extentions of text depending on font size.
            HOperatorSet.GetFontExtents(hv_ExpDefaultWinHandle, out hv_MaxAscent, out hv_MaxDescent,
                out hv_MaxWidth, out hv_MaxHeight);
            if ((int)(new HTuple(hv_CoordSystem.TupleEqual("window"))) != 0)
            {
                hv_R1 = hv_Row_COPY_INP_TMP.Clone();
                hv_C1 = hv_Column_COPY_INP_TMP.Clone();
            }
            else
            {
                //transform image to window coordinates
                hv_FactorRow = (1.0 * hv_HeightWin) / ((hv_Row2Part - hv_Row1Part) + 1);
                hv_FactorColumn = (1.0 * hv_WidthWin) / ((hv_Column2Part - hv_Column1Part) + 1);
                hv_R1 = ((hv_Row_COPY_INP_TMP - hv_Row1Part) + 0.5) * hv_FactorRow;
                hv_C1 = ((hv_Column_COPY_INP_TMP - hv_Column1Part) + 0.5) * hv_FactorColumn;
            }
            //
            //display text box depending on text size
            if ((int)(new HTuple(hv_Box.TupleEqual("true"))) != 0)
            {
                //calculate box extents
                hv_String_COPY_INP_TMP = (" " + hv_String_COPY_INP_TMP) + " ";
                hv_Width = new HTuple();
                for (hv_Index = 0; (int)hv_Index <= (int)((new HTuple(hv_String_COPY_INP_TMP.TupleLength()
                    )) - 1); hv_Index = (int)hv_Index + 1)
                {
                    HOperatorSet.GetStringExtents(hv_ExpDefaultWinHandle, hv_String_COPY_INP_TMP.TupleSelect(
                        hv_Index), out hv_Ascent, out hv_Descent, out hv_W, out hv_H);
                    hv_Width = hv_Width.TupleConcat(hv_W);
                }
                hv_FrameHeight = hv_MaxHeight * (new HTuple(hv_String_COPY_INP_TMP.TupleLength()
                    ));
                hv_FrameWidth = (((new HTuple(0)).TupleConcat(hv_Width))).TupleMax();
                hv_R2 = hv_R1 + hv_FrameHeight;
                hv_C2 = hv_C1 + hv_FrameWidth;
                //display rectangles
                HOperatorSet.GetDraw(hv_ExpDefaultWinHandle, out hv_DrawMode);
                HOperatorSet.SetDraw(hv_ExpDefaultWinHandle, "fill");
                HOperatorSet.SetColor(hv_ExpDefaultWinHandle, "light gray");
                HOperatorSet.DispRectangle1(hv_ExpDefaultWinHandle, hv_R1 + 3, hv_C1 + 3, hv_R2 + 3,
                    hv_C2 + 3);
                HOperatorSet.SetColor(hv_ExpDefaultWinHandle, "white");
                HOperatorSet.DispRectangle1(hv_ExpDefaultWinHandle, hv_R1, hv_C1, hv_R2, hv_C2);
                HOperatorSet.SetDraw(hv_ExpDefaultWinHandle, hv_DrawMode);
            }
            else if ((int)(new HTuple(hv_Box.TupleNotEqual("false"))) != 0)
            {
                hv_Exception = "Wrong value of control parameter Box";
                throw new HalconException(hv_Exception);
            }
            //Write text.
            for (hv_Index = 0; (int)hv_Index <= (int)((new HTuple(hv_String_COPY_INP_TMP.TupleLength()
                )) - 1); hv_Index = (int)hv_Index + 1)
            {
                hv_CurrentColor = hv_Color_COPY_INP_TMP.TupleSelect(hv_Index % (new HTuple(hv_Color_COPY_INP_TMP.TupleLength()
                    )));
                if ((int)((new HTuple(hv_CurrentColor.TupleNotEqual(""))).TupleAnd(new HTuple(hv_CurrentColor.TupleNotEqual(
                    "auto")))) != 0)
                {
                    HOperatorSet.SetColor(hv_ExpDefaultWinHandle, hv_CurrentColor);
                }
                else
                {
                    HOperatorSet.SetRgb(hv_ExpDefaultWinHandle, hv_Red, hv_Green, hv_Blue);
                }
                hv_Row_COPY_INP_TMP = hv_R1 + (hv_MaxHeight * hv_Index);
                HOperatorSet.SetTposition(hv_ExpDefaultWinHandle, hv_Row_COPY_INP_TMP, hv_C1);
                HOperatorSet.WriteString(hv_ExpDefaultWinHandle, hv_String_COPY_INP_TMP.TupleSelect(
                    hv_Index));
            }
            //reset changed window settings
            HOperatorSet.SetRgb(hv_ExpDefaultWinHandle, hv_Red, hv_Green, hv_Blue);
            HOperatorSet.SetPart(hv_ExpDefaultWinHandle, hv_Row1Part, hv_Column1Part, hv_Row2Part,
                hv_Column2Part);

            return;
        }

        // Chapter: XLD / Creation
        // Short Description: Creates an arrow shaped XLD contour.
        public void gen_arrow_contour_xld(out HObject ho_Arrow, HTuple hv_Row1, HTuple hv_Column1,
            HTuple hv_Row2, HTuple hv_Column2, HTuple hv_HeadLength, HTuple hv_HeadWidth)
        {


            // Stack for temporary objects 
            HObject[] OTemp = new HObject[20];
            long SP_O = 0;

            // Local iconic variables 

            HObject ho_TempArrow = null;


            // Local control variables 

            HTuple hv_Length, hv_ZeroLengthIndices, hv_DR;
            HTuple hv_DC, hv_HalfHeadWidth, hv_RowP1, hv_ColP1, hv_RowP2;
            HTuple hv_ColP2, hv_Index;

            // Initialize local and output iconic variables 
            HOperatorSet.GenEmptyObj(out ho_Arrow);
            HOperatorSet.GenEmptyObj(out ho_TempArrow);

            try
            {
                //This procedure generates arrow shaped XLD contours,
                //pointing from (Row1, Column1) to (Row2, Column2).
                //If starting and end point are identical, a contour consisting
                //of a single point is returned.
                //
                //input parameteres:
                //Row1, Column1: Coordinates of the arrows' starting points
                //Row2, Column2: Coordinates of the arrows' end points
                //HeadLength, HeadWidth: Size of the arrow heads in pixels
                //
                //output parameter:
                //Arrow: The resulting XLD contour
                //
                //The input tuples Row1, Column1, Row2, and Column2 have to be of
                //the same length.
                //HeadLength and HeadWidth either have to be of the same length as
                //Row1, Column1, Row2, and Column2 or have to be a single element.
                //If one of the above restrictions is violated, an error will occur.
                //
                //
                //Init
                ho_Arrow.Dispose();
                HOperatorSet.GenEmptyObj(out ho_Arrow);
                //
                //Calculate the arrow length
                HOperatorSet.DistancePp(hv_Row1, hv_Column1, hv_Row2, hv_Column2, out hv_Length);
                //
                //Mark arrows with identical start and end point
                //(set Length to -1 to avoid division-by-zero exception)
                hv_ZeroLengthIndices = hv_Length.TupleFind(0);
                if ((int)(new HTuple(hv_ZeroLengthIndices.TupleNotEqual(-1))) != 0)
                {
                    hv_Length[hv_ZeroLengthIndices] = -1;
                }
                //
                //Calculate auxiliary variables.
                hv_DR = (1.0 * (hv_Row2 - hv_Row1)) / hv_Length;
                hv_DC = (1.0 * (hv_Column2 - hv_Column1)) / hv_Length;
                hv_HalfHeadWidth = hv_HeadWidth / 2.0;
                //
                //Calculate end points of the arrow head.
                hv_RowP1 = (hv_Row1 + ((hv_Length - hv_HeadLength) * hv_DR)) + (hv_HalfHeadWidth * hv_DC);
                hv_ColP1 = (hv_Column1 + ((hv_Length - hv_HeadLength) * hv_DC)) - (hv_HalfHeadWidth * hv_DR);
                hv_RowP2 = (hv_Row1 + ((hv_Length - hv_HeadLength) * hv_DR)) - (hv_HalfHeadWidth * hv_DC);
                hv_ColP2 = (hv_Column1 + ((hv_Length - hv_HeadLength) * hv_DC)) + (hv_HalfHeadWidth * hv_DR);
                //
                //Finally create output XLD contour for each input point pair
                for (hv_Index = 0; (int)hv_Index <= (int)((new HTuple(hv_Length.TupleLength())) - 1); hv_Index = (int)hv_Index + 1)
                {
                    if ((int)(new HTuple(((hv_Length.TupleSelect(hv_Index))).TupleEqual(-1))) != 0)
                    {
                        //Create_ single points for arrows with identical start and end point
                        ho_TempArrow.Dispose();
                        HOperatorSet.GenContourPolygonXld(out ho_TempArrow, hv_Row1.TupleSelect(
                            hv_Index), hv_Column1.TupleSelect(hv_Index));
                    }
                    else
                    {
                        //Create arrow contour
                        ho_TempArrow.Dispose();
                        HOperatorSet.GenContourPolygonXld(out ho_TempArrow, ((((((((((hv_Row1.TupleSelect(
                            hv_Index))).TupleConcat(hv_Row2.TupleSelect(hv_Index)))).TupleConcat(
                            hv_RowP1.TupleSelect(hv_Index)))).TupleConcat(hv_Row2.TupleSelect(hv_Index)))).TupleConcat(
                            hv_RowP2.TupleSelect(hv_Index)))).TupleConcat(hv_Row2.TupleSelect(hv_Index)),
                            ((((((((((hv_Column1.TupleSelect(hv_Index))).TupleConcat(hv_Column2.TupleSelect(
                            hv_Index)))).TupleConcat(hv_ColP1.TupleSelect(hv_Index)))).TupleConcat(
                            hv_Column2.TupleSelect(hv_Index)))).TupleConcat(hv_ColP2.TupleSelect(
                            hv_Index)))).TupleConcat(hv_Column2.TupleSelect(hv_Index)));
                    }
                    OTemp[SP_O] = ho_Arrow.CopyObj(1, -1);
                    SP_O++;
                    ho_Arrow.Dispose();
                    HOperatorSet.ConcatObj(OTemp[SP_O - 1], ho_TempArrow, out ho_Arrow);
                    OTemp[SP_O - 1].Dispose();
                    SP_O = 0;
                }
                ho_TempArrow.Dispose();

                return;
            }
            catch (HalconException HDevExpDefaultException)
            {
                ho_TempArrow.Dispose();

                throw HDevExpDefaultException;
            }
        }

        // Main procedure 
        private void action()
        {
            // Initialize local and output iconic variables 
            HOperatorSet.GenEmptyObj(out ho_Mark);

            HOperatorSet.OpenFramegrabber("DahengCAM", 1, 1, 0, 0, 0, 0, "interlaced", 8,
                "rgb", -1, "false", "HV-13xx", "1", 1, -1, out hv_AcqHandle);
            HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "adc_level", "adc1");
            HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "gain", 16);
            HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "shutter", 10);
            HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "white_balance_b", 1.36);
            HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "white_balance_r", 1.59);
            HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "bayer_layout", "bayer_bg");
            HOperatorSet.SetFramegrabberParam(hv_AcqHandle, "color_space", "RGB");
            //HOperatorSet.GrabImageStart(hv_AcqHandle, -1);
            ho_Mark.Dispose();
            HOperatorSet.GrabImage(out ho_Mark, hv_AcqHandle);
            //HDevelopStop();

            //ho_Mark.Dispose();
            //HOperatorSet.GrabImageAsync(out ho_Mark, hv_AcqHandle, -1);

            HOperatorSet.DispObj(ho_Mark, hv_ExpDefaultWinHandle);
            //HOperatorSet.CloseFramegrabber(hv_AcqHandle);


            //ho_Mark.Dispose();

        }
        public void graberImage()
        {
            //HOperatorSet.GrabImageStart(hv_AcqHandle, -1);
        }
        public void updateImage()
        {
            ho_Mark.Dispose();
            //HOperatorSet.GrabImageAsync(out ho_Mark, hv_AcqHandle, -1);
            HOperatorSet.GrabImage(out ho_Mark, hv_AcqHandle);
            HOperatorSet.DispObj(ho_Mark, hv_ExpDefaultWinHandle);
            
        }
        public void closeFrameGrabber()
        {
            HOperatorSet.CloseFramegrabber(hv_AcqHandle);
            ho_Mark.Dispose();
        }
        public void findMark()
        {
            // Local iconic variables 

            HObject ho_ImageSmooth, ho_GrayImage;
            HObject ho_Region, ho_DarkRegions, ho_Circles, ho_ROIOuter;
            HObject ho_ROIInner, ho_ROI, ho_ImageReduced1, ho_Edges;
            HObject ho_SelectedXLD, ho_Arrow, ho_ContCircle, ho_Cross;

            /// Local control variables 

            HTuple hv_Row, hv_Column, hv_StartPhi;
            HTuple hv_EndPhi, hv_PointOrder, hv_Radius;

            // Initialize local and output iconic variables 
            HOperatorSet.GenEmptyObj(out ho_Mark);
            HOperatorSet.GenEmptyObj(out ho_GrayImage);
            HOperatorSet.GenEmptyObj(out ho_ImageSmooth);
            HOperatorSet.GenEmptyObj(out ho_Region);
            HOperatorSet.GenEmptyObj(out ho_DarkRegions);
            HOperatorSet.GenEmptyObj(out ho_Circles);
            HOperatorSet.GenEmptyObj(out ho_ROIOuter);
            HOperatorSet.GenEmptyObj(out ho_ROIInner);
            HOperatorSet.GenEmptyObj(out ho_ROI);
            HOperatorSet.GenEmptyObj(out ho_ImageReduced1);
            HOperatorSet.GenEmptyObj(out ho_Edges);
            HOperatorSet.GenEmptyObj(out ho_SelectedXLD);
            HOperatorSet.GenEmptyObj(out ho_Arrow);
            HOperatorSet.GenEmptyObj(out ho_ContCircle);
            HOperatorSet.GenEmptyObj(out ho_Cross);


            try
            {
                ho_Mark.Dispose();
                HOperatorSet.GrabImage(out ho_Mark, hv_AcqHandle);
                HOperatorSet.DispObj(ho_Mark, hv_ExpDefaultWinHandle);

                ho_GrayImage.Dispose();
                HOperatorSet.Rgb1ToGray(ho_Mark, out ho_GrayImage);

                ho_ImageSmooth.Dispose();
                HOperatorSet.MeanImage(ho_GrayImage, out ho_ImageSmooth, 5, 5);
                //smooth_image (ImageMean, ImageSmooth, 'deriche2', 0.75)

                ho_Region.Dispose();
                HOperatorSet.Threshold(ho_ImageSmooth, out ho_Region, 150, 255);
                ho_DarkRegions.Dispose();
                HOperatorSet.Connection(ho_Region, out ho_DarkRegions);

                ho_Circles.Dispose();
                HOperatorSet.SelectShape(ho_DarkRegions, out ho_Circles, (new HTuple("circularity")).TupleConcat(
                    "area"), "and", (new HTuple(0.7)).TupleConcat(2000), (new HTuple(1)).TupleConcat(
                    99000));

                ho_ROIOuter.Dispose();
                HOperatorSet.DilationCircle(ho_Circles, out ho_ROIOuter, 5);
                ho_ROIInner.Dispose();
                HOperatorSet.ErosionCircle(ho_Circles, out ho_ROIInner, 5);
                ho_ROI.Dispose();
                HOperatorSet.Difference(ho_ROIOuter, ho_ROIInner, out ho_ROI);
                ho_ImageReduced1.Dispose();
                HOperatorSet.ReduceDomain(ho_ImageSmooth, ho_ROI, out ho_ImageReduced1);

                ho_Edges.Dispose();
                HOperatorSet.EdgesSubPix(ho_ImageReduced1, out ho_Edges, "canny", 1, 20, 40);
                ho_SelectedXLD.Dispose();
                HOperatorSet.SelectShapeXld(ho_Edges, out ho_SelectedXLD, "contlength", "and",
                    20, 99999);

                //fit_ellipse_contour_xld (SelectedXLD, 'fitzgibbon', -1, 0, 0, 200, 3, 2, Row, Column, Phi, Radius1, Radius2, StartPhi, EndPhi, PointOrder)
                HOperatorSet.FitCircleContourXld(ho_SelectedXLD, "algebraic", -1, 0, 0, 3,
                    2, out hv_Row, out hv_Column, out hv_Radius, out hv_StartPhi, out hv_EndPhi,
                    out hv_PointOrder);
                ho_Arrow.Dispose();
                gen_arrow_contour_xld(out ho_Arrow, hv_Row, hv_Column, hv_Row, hv_Column + hv_Radius,
                    15, 15);
                ho_ContCircle.Dispose();
                HOperatorSet.GenCircleContourXld(out ho_ContCircle, hv_Row, hv_Column, hv_Radius,
                    0, 6.28318, "positive", 1);
                HOperatorSet.DispObj(ho_Mark, hv_ExpDefaultWinHandle);
                HOperatorSet.SetColor(hv_ExpDefaultWinHandle, "red");
                HOperatorSet.DispObj(ho_ContCircle, hv_ExpDefaultWinHandle);
                HOperatorSet.DispObj(ho_Arrow, hv_ExpDefaultWinHandle);
                ho_Cross.Dispose();
                HOperatorSet.GenCrossContourXld(out ho_Cross, hv_Row, hv_Column, 16, 0.785398);
                disp_message(hv_ExpDefaultWinHandle, "直径为：" + (2 * hv_Radius), "window",
                    20, 20, "green", "true");
                disp_message(hv_ExpDefaultWinHandle, (("位置为：" + hv_Row) + ",") + hv_Column,
                    "window", 40, 20, "blue", "true");

            }
            catch (HalconException HDevExpDefaultException)
            {
                ho_Mark.Dispose();
                ho_GrayImage.Dispose();
                ho_ImageSmooth.Dispose();
                ho_Region.Dispose();
                ho_DarkRegions.Dispose();
                ho_Circles.Dispose();
                ho_ROIOuter.Dispose();
                ho_ROIInner.Dispose();
                ho_ROI.Dispose();
                ho_ImageReduced1.Dispose();
                ho_Edges.Dispose();
                ho_SelectedXLD.Dispose();
                ho_Arrow.Dispose();
                ho_ContCircle.Dispose();
                ho_Cross.Dispose();

                throw HDevExpDefaultException;
            }
            ho_Mark.Dispose();
            ho_GrayImage.Dispose();
            ho_ImageSmooth.Dispose();
            ho_Region.Dispose();
            ho_DarkRegions.Dispose();
            ho_Circles.Dispose();
            ho_ROIOuter.Dispose();
            ho_ROIInner.Dispose();
            ho_ROI.Dispose();
            ho_ImageReduced1.Dispose();
            ho_Edges.Dispose();
            ho_SelectedXLD.Dispose();
            ho_Arrow.Dispose();
            ho_ContCircle.Dispose();
            ho_Cross.Dispose();
        }

        public void InitHalcon()
        {
            // Default settings used in HDevelop 
            HOperatorSet.SetSystem("do_low_error", "false");
        }

        public void RunHalcon(HTuple Window)
        {
            hv_ExpDefaultWinHandle = Window;
            action();
        }

    }
}
